Delete read functionality for the old-style binary profile format.

RELNOTES[INC]: The old-style binary profile format is no longer suppported, use the new JSON trace profile instead.

PiperOrigin-RevId: 298574830
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/Profiler.java b/src/main/java/com/google/devtools/build/lib/profiler/Profiler.java
index 70c8070..85c8a74 100644
--- a/src/main/java/com/google/devtools/build/lib/profiler/Profiler.java
+++ b/src/main/java/com/google/devtools/build/lib/profiler/Profiler.java
@@ -66,74 +66,14 @@
  * build.lib.vfs contain Profiler invocations and any dependency on those two packages would create
  * circular relationship.
  *
- * <p>All gathered instrumentation data will be stored in the file. Please, note, that while file
- * format is described here it is considered internal and can change at any time. For scripting,
- * using blaze analyze-profile --dump=raw would be more robust and stable solution.
- *
  * <p>
  *
- * <pre>
- * Profiler file consists of the deflated stream with following overall structure:
- *   HEADER
- *   TASK_TYPE_TABLE
- *   TASK_RECORD...
- *   EOF_MARKER
- *
- * HEADER:
- *   int32: magic token (Profiler.MAGIC)
- *   int32: version format (Profiler.VERSION)
- *   string: file comment
- *
- * TASK_TYPE_TABLE:
- *   int32: number of type names below
- *   string... : type names. Each of the type names is assigned id according to
- *               their position in this table starting from 0.
- *
- * TASK_RECORD:
- *   int32 size: size of the encoded task record
- *   byte[size] encoded_task_record:
- *     varint64: thread id - as was returned by Thread.getId()
- *     varint32: task id - starting from 1.
- *     varint32: parent task id for subtasks or 0 for root tasks
- *     varint64: start time in ns, relative to the Profiler.start() invocation
- *     varint64: task duration in ns
- *     byte:     task type id (see TASK_TYPE_TABLE)
- *     varint32: description string index incremented by 1 (>0) or 0 this is
- *               a first occurrence of the description string
- *     AGGREGATED_STAT...: remainder of the field (if present) represents
- *                         aggregated stats for that task
- *   string: *optional* description string, will appear only if description
- *           string index above was 0. In that case this string will be
- *           assigned next sequential id so every unique description string
- *           will appear in the file only once - after that it will be
- *           referenced by id.
- *
- * AGGREGATE_STAT:
- *   byte:     stat type
- *   varint32: total number of subtask invocations
- *   varint64: cumulative duration of subtask invocations in ns.
- *
- * EOF_MARKER:
- *   int64: -1 - please note that this corresponds to the thread id in the
- *               TASK_RECORD which is always > 0
- * </pre>
- *
  * @see ProfilerTask enum for recognized task types.
  */
 @ThreadSafe
 public final class Profiler {
   private static final Logger logger = Logger.getLogger(Profiler.class.getName());
 
-  public static final int MAGIC = 0x11223344;
-
-  // File version number. Note that merely adding new record types in
-  // the ProfilerTask does not require bumping version number as long as original
-  // enum values are not renamed or deleted.
-  public static final int VERSION = 0x03;
-
-  // EOF marker. Must be < 0.
-  public static final int EOF_MARKER = -1;
-
   /** The profiler (a static singleton instance). Inactive by default. */
   private static final Profiler instance = new Profiler();
 
@@ -146,7 +86,7 @@
   /** File format enum. */
   public enum Format {
     JSON_TRACE_FILE_FORMAT,
-    JSON_TRACE_FILE_COMPRESSED_FORMAT;
+    JSON_TRACE_FILE_COMPRESSED_FORMAT
   }
 
   /** A task that was very slow. */
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java b/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java
index fc39cdf..13974e5 100644
--- a/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java
+++ b/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java
@@ -107,14 +107,14 @@
   /** True if the metric records VFS operations */
   private final boolean vfs;
 
-  private ProfilerTask(String description, long minDuration, int slowestInstanceCount) {
+  ProfilerTask(String description, long minDuration, int slowestInstanceCount) {
     this.description = description;
     this.minDuration = minDuration;
     this.slowestInstancesCount = slowestInstanceCount;
     this.vfs = this.name().startsWith("VFS");
   }
 
-  private ProfilerTask(String description) {
+  ProfilerTask(String description) {
     this(description, /* minDuration= */ -1, /* slowestInstanceCount= */ 0);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/analysis/ProfileInfo.java b/src/main/java/com/google/devtools/build/lib/profiler/analysis/ProfileInfo.java
deleted file mode 100644
index 83b44b0..0000000
--- a/src/main/java/com/google/devtools/build/lib/profiler/analysis/ProfileInfo.java
+++ /dev/null
@@ -1,612 +0,0 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.profiler.analysis;
-
-import static com.google.devtools.build.lib.profiler.ProfilerTask.TASK_COUNT;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.devtools.build.lib.profiler.ProfilePhase;
-import com.google.devtools.build.lib.profiler.Profiler;
-import com.google.devtools.build.lib.profiler.ProfilerTask;
-import com.google.devtools.build.lib.util.VarInt;
-import com.google.devtools.build.lib.vfs.Path;
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.zip.Inflater;
-import java.util.zip.InflaterInputStream;
-
-/**
- * Holds parsed profile file information and provides various ways of
- * accessing it (mostly through different dictionaries or sorted lists).
- *
- * <p>Class should not be instantiated directly but through the use of the
- * ProfileLoader.loadProfile() method.
- */
-public class ProfileInfo {
-
-  /**
-   * Immutable container for the aggregated stats.
-   */
-  public static final class AggregateAttr {
-    public final int count;
-    public final long totalTime;
-
-    AggregateAttr(int count, long totalTime) {
-      this.count = count;
-      this.totalTime = totalTime;
-    }
-  }
-
-  /** Immutable compact representation of the Map<ProfilerTask, AggregateAttr>. */
-  public static final class CompactStatistics {
-    final byte[] content;
-
-    CompactStatistics(byte[] content) {
-      this.content = content;
-    }
-
-    /**
-     * Create compact task statistic instance using provided array.
-     * Array length must exactly match ProfilerTask value space.
-     * Each statistic is stored in the array according to the ProfilerTask
-     * value ordinal() number. Absent statistics are represented by null.
-     */
-    CompactStatistics(AggregateAttr[] stats) {
-      Preconditions.checkArgument(stats.length == TASK_COUNT);
-      ByteBuffer sink = ByteBuffer.allocate(TASK_COUNT * (1 + 5 + 10));
-      for (int i = 0; i < TASK_COUNT; i++) {
-        if (stats[i] != null && stats[i].count > 0) {
-          sink.put((byte) i);
-          VarInt.putVarInt(stats[i].count, sink);
-          VarInt.putVarLong(stats[i].totalTime, sink);
-        }
-      }
-      content = sink.position() > 0 ? Arrays.copyOf(sink.array(), sink.position()) : null;
-    }
-
-    public boolean isEmpty() {
-      return content == null;
-    }
-
-    /**
-     * Converts instance back into AggregateAttr[TASK_COUNT]. See constructor documentation for more
-     * information.
-     */
-    public AggregateAttr[] toArray() {
-      AggregateAttr[] stats = new AggregateAttr[TASK_COUNT];
-      if (!isEmpty()) {
-        ByteBuffer source = ByteBuffer.wrap(content);
-        while (source.hasRemaining()) {
-          byte id = source.get();
-          int count = VarInt.getVarInt(source);
-          long time = VarInt.getVarLong(source);
-          stats[id] = new AggregateAttr(count, time);
-        }
-      }
-      return stats;
-    }
-
-    /** Returns AggregateAttr instance for the given ProfilerTask value. */
-    public AggregateAttr getAttr(ProfilerTask task) {
-      if (isEmpty()) { return ZERO; }
-      ByteBuffer source = ByteBuffer.wrap(content);
-      byte id = (byte) task.ordinal();
-      while (source.hasRemaining()) {
-        if (id == source.get()) {
-          int count = VarInt.getVarInt(source);
-          long time = VarInt.getVarLong(source);
-          return new AggregateAttr(count, time);
-        } else {
-          VarInt.getVarInt(source);
-          VarInt.getVarLong(source);
-        }
-      }
-      return ZERO;
-    }
-
-    /**
-     * Returns cumulative time stored in this instance across whole
-     * ProfilerTask dimension.
-     */
-    long getTotalTime() {
-      if (isEmpty()) { return 0; }
-      ByteBuffer source = ByteBuffer.wrap(content);
-      long totalTime = 0;
-      while (source.hasRemaining()) {
-        source.get();
-        VarInt.getVarInt(source);
-        totalTime += VarInt.getVarLong(source);
-      }
-      return totalTime;
-    }
-  }
-
-  /**
-   * Container for the profile record information.
-   *
-   * <p> TODO(bazel-team): (2010) Current Task instance heap size is 72 bytes. And there are
-   * millions of them. Consider trimming some attributes.
-   */
-  public final class Task implements Comparable<Task> {
-    public final long threadId;
-    public final int id;
-    public final int parentId;
-    public final long startTime;
-    public final long durationNanos;
-    public final ProfilerTask type;
-    public final CompactStatistics stats;
-    // Contains statistic for a task and all subtasks. Populated only for root tasks.
-    public CompactStatistics aggregatedStats = null;
-    // Subtasks are stored as an array for performance and memory utilization
-    // reasons (we can easily deal with millions of those objects).
-    public Task[] subtasks = NO_TASKS;
-    final int descIndex;
-    // Reference to the related task (e.g. ACTION_GRAPH->ACTION task relation).
-    private Task relatedTask;
-
-    Task(
-        long threadId,
-        int id,
-        int parentId,
-        long startTime,
-        long durationNanos,
-        ProfilerTask type,
-        int descIndex,
-        CompactStatistics stats) {
-      this.threadId = threadId;
-      this.id = id;
-      this.parentId = parentId;
-      this.startTime = startTime;
-      this.durationNanos = durationNanos;
-      this.type = type;
-      this.descIndex = descIndex;
-      this.stats = stats;
-      relatedTask = null;
-    }
-
-    public String getDescription() {
-      return descriptionList.get(descIndex);
-    }
-
-    public boolean hasStats() {
-      return !stats.isEmpty();
-    }
-
-    public long getInheritedDuration() {
-      return stats.getTotalTime();
-    }
-
-    public AggregateAttr[] getStatAttrArray() {
-      Preconditions.checkNotNull(stats);
-      return stats.toArray();
-    }
-
-    private void combineStats(int[] counts, long[] duration) {
-      int ownIndex = type.ordinal();
-      if (parentId != 0) {
-        // Parent task already accounted for this task total duration. We need to adjust
-        // for the inherited duration.
-        duration[ownIndex] -= getInheritedDuration();
-      }
-      AggregateAttr[] ownStats = stats.toArray();
-      for (int i = 0; i < TASK_COUNT; i++) {
-        AggregateAttr attr = ownStats[i];
-        if (attr != null) {
-          counts[i] += attr.count;
-          duration[i] += attr.totalTime;
-        }
-      }
-      for (Task task : subtasks) {
-        task.combineStats(counts, duration);
-      }
-    }
-
-    /**
-     * Calculates aggregated statistics covering all subtasks (including
-     * nested ones). Must be called only for parent tasks.
-     */
-    void calculateRootStats() {
-      Preconditions.checkState(parentId == 0);
-      int[] counts = new int[TASK_COUNT];
-      long[] duration = new long[TASK_COUNT];
-      combineStats(counts, duration);
-      AggregateAttr[] statArray = ProfileInfo.createEmptyStatArray();
-      for (int i = 0; i < TASK_COUNT; i++) {
-        statArray[i] = new AggregateAttr(counts[i], duration[i]);
-      }
-      this.aggregatedStats = new CompactStatistics(statArray);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      return (o instanceof ProfileInfo.Task) && ((Task) o).id == this.id;
-    }
-
-    @Override
-    public int hashCode() {
-      return this.id;
-    }
-
-    @Override
-    public String toString() {
-      return type + "(" + id + "," + getDescription() + ")";
-    }
-
-    /**
-     * Tasks records by default sorted by their id. Since id was obtained using
-     * AtomicInteger, this comparison will correctly sort tasks in time-ascending
-     * order regardless of their origin thread.
-     */
-    @Override
-    public int compareTo(Task task) {
-      return this.id - task.id;
-    }
-  }
-
-  /**
-   * Helper class to create space-efficient task multimap, used to associate
-   * array of tasks with specific key.
-   */
-  private abstract static class TaskMapCreator<K> implements Comparator<Task> {
-    @Override
-    public abstract int compare(Task a, Task b);
-    public abstract K getKey(Task task);
-
-    public Map<K, Task[]> createTaskMap(List<Task> taskList) {
-      // Created map usually will end up with thousands of entries, so we
-      // preinitialize it to the 10000.
-      Map<K, Task[]> taskMap = Maps.newHashMapWithExpectedSize(10000);
-      if (taskList.isEmpty()) {
-        return taskMap;
-      }
-      Task[] taskArray = taskList.toArray(new Task[taskList.size()]);
-      Arrays.sort(taskArray, this);
-      K key = getKey(taskArray[0]);
-      int start = 0;
-      for (int i = 0; i < taskArray.length; i++) {
-        K currentKey = getKey(taskArray[i]);
-        if (!key.equals(currentKey)) {
-          taskMap.put(key, Arrays.copyOfRange(taskArray, start, i));
-          key = currentKey;
-          start = i;
-        }
-      }
-      if (start < taskArray.length) {
-        taskMap.put(key, Arrays.copyOfRange(taskArray, start, taskArray.length));
-      }
-      return taskMap;
-    }
-  }
-
-  /**
-   * An interface to pass back profile loading and aggregation messages.
-   */
-  public interface InfoListener {
-    void info(String text);
-    void warn(String text);
-  }
-
-  private static final Task[] NO_TASKS = new Task[0];
-  private static final AggregateAttr ZERO = new AggregateAttr(0, 0);
-
-  public final String comment;
-  private long minTaskStartTime = Long.MAX_VALUE;
-  private boolean corruptedOrIncomplete = false;
-
-  // TODO(bazel-team): (2010) In one case, this list took 277MB of heap. Ideally it should be
-  // replaced with a trie.
-  private final List<String> descriptionList;
-  public final List<Task> allTasksById;
-  public List<Task> rootTasksById;  // Not final due to the late initialization.
-  public final List<Task> phaseTasks;
-
-  private ProfileInfo(String comment) {
-    this.comment = comment;
-
-    descriptionList = Lists.newArrayListWithExpectedSize(10000);
-    allTasksById = Lists.newArrayListWithExpectedSize(50000);
-    phaseTasks = Lists.newArrayList();
-  }
-
-  private void addTask(Task task) {
-    allTasksById.add(task);
-    minTaskStartTime = Math.min(minTaskStartTime, task.startTime);
-  }
-
-  /**
-   * Returns true if profile datafile was corrupted or incomplete
-   * and false otherwise.
-   */
-  public boolean isCorruptedOrIncomplete() {
-    return corruptedOrIncomplete;
-  }
-
-  /**
-   * Initializes minimum internal data structures necessary to obtain individual
-   * task statistic. This method is sufficient to initialize data for dumping.
-   */
-  public void calculateStats() {
-    if (allTasksById.isEmpty()) {
-      return;
-    }
-
-    Collections.sort(allTasksById);
-
-    Map<Integer, Task[]> subtaskMap = new TaskMapCreator<Integer>() {
-      @Override
-      public int compare(Task a, Task b) {
-        return a.parentId != b.parentId ? a.parentId - b.parentId : a.compareTo(b);
-      }
-      @Override
-      public Integer getKey(Task task) { return task.parentId; }
-    }.createTaskMap(allTasksById);
-    for (Task task : allTasksById) {
-      Task[] subtasks = subtaskMap.get(task.id);
-      if (subtasks != null) {
-        task.subtasks = subtasks;
-      }
-    }
-    rootTasksById = Arrays.asList(subtaskMap.get(0));
-
-    for (Task task : rootTasksById) {
-      task.calculateRootStats();
-      if (task.type == ProfilerTask.PHASE) {
-        if (!phaseTasks.isEmpty()) {
-          phaseTasks.get(phaseTasks.size() - 1).relatedTask = task;
-        }
-        phaseTasks.add(task);
-      }
-    }
-  }
-
-  /**
-   * Calculates cumulative time attributed to the specific task type.
-   * Expects to be called only for root (parentId = 0) tasks.
-   * calculateStats() must have been called first.
-   */
-  public AggregateAttr getStatsForType(ProfilerTask type, Collection<Task> tasks) {
-    long totalTime = 0;
-    int count = 0;
-    for (Task task : tasks) {
-      if (task.parentId > 0) {
-        throw new IllegalArgumentException("task " + task.id + " is not a root task");
-      }
-      AggregateAttr attr = task.aggregatedStats.getAttr(type);
-      count += attr.count;
-      totalTime += attr.totalTime;
-      if (task.type == type) {
-        count++;
-        totalTime += (task.durationNanos - task.getInheritedDuration());
-      }
-    }
-    return new AggregateAttr(count, totalTime);
-  }
-
-  /**
-   * Returns list of all root tasks related to (in other words, started during)
-   * the specified phase task.
-   */
-  public List<Task> getTasksForPhase(Task phaseTask) {
-    Preconditions.checkArgument(phaseTask.type == ProfilerTask.PHASE,
-      "Unsupported task type %s", phaseTask.type);
-
-    // Algorithm below takes into account fact that rootTasksById list is sorted
-    // by the task id and task id values are monotonically increasing with time
-    // (this property is guaranteed by the profiler). Thus list is effectively
-    // sorted by the startTime. We are trying to select a sublist that includes
-    // all tasks that were started later than the given task but earlier than
-    // its completion time.
-    int startIndex = Collections.binarySearch(rootTasksById, phaseTask);
-    Preconditions.checkState(startIndex >= 0,
-        "Phase task %s is not a root task", phaseTask.id);
-    int endIndex = (phaseTask.relatedTask != null)
-        ? Collections.binarySearch(rootTasksById, phaseTask.relatedTask)
-        : rootTasksById.size();
-    Preconditions.checkState(endIndex >= startIndex,
-        "Failed to find end of the phase marked by the task %s", phaseTask.id);
-    return rootTasksById.subList(startIndex, endIndex);
-  }
-
-  /**
-   * Returns task with "Build artifacts" description - corresponding to the
-   * execution phase. Usually used to location ACTION_GRAPH task tree.
-   */
-  public Task getPhaseTask(ProfilePhase phase) {
-    for (Task task : phaseTasks) {
-      if (task.getDescription().equals(phase.description)) {
-        return task;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Returns duration of the given phase in ns.
-   */
-  public long getPhaseDuration(Task phaseTask) {
-    Preconditions.checkArgument(phaseTask.type == ProfilerTask.PHASE,
-        "Unsupported task type %s", phaseTask.type);
-
-    long duration;
-    if (phaseTask.relatedTask != null) {
-      duration = phaseTask.relatedTask.startTime - phaseTask.startTime;
-    } else {
-      Task lastTask = rootTasksById.get(rootTasksById.size() - 1);
-      duration = lastTask.startTime + lastTask.durationNanos - phaseTask.startTime;
-    }
-    Preconditions.checkState(duration >= 0);
-    return duration;
-  }
-
-  /**
-   * Returns an empty array used to store task statistics. Array index
-   * corresponds to the ProfilerTask ordinal() value associated with the
-   * given statistic. Absent statistics are stored as null.
-   * <p>
-   * In essence, it is a fast equivalent of Map<ProfilerTask, AggregateAttr>.
-   */
-  public static AggregateAttr[] createEmptyStatArray() {
-    return new AggregateAttr[TASK_COUNT];
-  }
-
-  /**
-   * Loads and parses Blaze profile file.
-   *
-   * @param profileStream profile file path
-   *
-   * @return ProfileInfo object with some fields populated (call calculateStats()
-   *         and analyzeRelationships() to populate the remaining fields)
-   * @throws UnsupportedEncodingException if the file format is invalid
-   * @throws IOException if the file can't be read
-   */
-  public static ProfileInfo loadProfile(InputStream profileStream) throws IOException {
-    // It is extremely important to wrap InflaterInputStream using BufferedInputStream because
-    // the majority of reads would be done using readInt()/readLong() methods and
-    // InflaterInputStream is very inefficient in handling small read requests (performance
-    // difference with 1MB buffer used below is almost 10x).
-    DataInputStream in =
-        new DataInputStream(
-            new BufferedInputStream(
-                new InflaterInputStream(profileStream, new Inflater(false), 65536), 1024 * 1024));
-
-    if (in.readInt() != Profiler.MAGIC) {
-      in.close();
-      throw new UnsupportedEncodingException("Invalid profile datafile format");
-    }
-    if (in.readInt() != Profiler.VERSION) {
-      in.close();
-      throw new UnsupportedEncodingException("Incompatible profile datafile version");
-    }
-    String fileComment = in.readUTF();
-
-    // Read list of used record types
-    int typeCount = in.readInt();
-    boolean hasUnknownTypes = false;
-    Set<String> supportedTasks = new HashSet<>();
-    for (ProfilerTask task : ProfilerTask.values()) {
-      supportedTasks.add(task.toString());
-    }
-    List<ProfilerTask> typeList = new ArrayList<>();
-    for (int i = 0; i < typeCount; i++) {
-      String name = in.readUTF();
-      if (supportedTasks.contains(name)) {
-        typeList.add(ProfilerTask.valueOf(name));
-      } else {
-        hasUnknownTypes = true;
-        typeList.add(ProfilerTask.UNKNOWN);
-      }
-    }
-
-    ProfileInfo info = new ProfileInfo(fileComment);
-
-    // Read record until we encounter end marker (-1).
-    // TODO(bazel-team): Maybe this still should handle corrupted(truncated) files.
-    try {
-      int size;
-      while ((size = in.readInt()) != Profiler.EOF_MARKER) {
-        byte[] backingArray = new byte[size];
-        in.readFully(backingArray);
-        ByteBuffer buffer = ByteBuffer.wrap(backingArray);
-        long threadId = VarInt.getVarLong(buffer);
-        int id = VarInt.getVarInt(buffer);
-        int parentId = VarInt.getVarInt(buffer);
-        long startTime = VarInt.getVarLong(buffer);
-        long duration = VarInt.getVarLong(buffer);
-        int descIndex = VarInt.getVarInt(buffer) - 1;
-        if (descIndex == -1) {
-          String desc = in.readUTF();
-          descIndex = info.descriptionList.size();
-          info.descriptionList.add(desc);
-        }
-        ProfilerTask type = typeList.get(buffer.get());
-        byte[] stats = null;
-        if (buffer.hasRemaining()) {
-          // Copy aggregated stats.
-          int offset = buffer.position();
-          stats = Arrays.copyOfRange(backingArray, offset, size);
-          if (hasUnknownTypes) {
-            while (buffer.hasRemaining()) {
-              byte attrType = buffer.get();
-              if (typeList.get(attrType) == ProfilerTask.UNKNOWN) {
-                // We're dealing with unknown aggregated type - update stats array to
-                // use ProfilerTask.UNKNOWN.ordinal() value.
-                stats[buffer.position() - 1 - offset] = (byte) ProfilerTask.UNKNOWN.ordinal();
-              }
-              VarInt.getVarInt(buffer);
-              VarInt.getVarLong(buffer);
-            }
-          }
-        }
-        ProfileInfo.Task task =  info.new Task(threadId, id, parentId, startTime, duration, type,
-            descIndex, new CompactStatistics(stats));
-        info.addTask(task);
-      }
-    } catch (IOException e) {
-      info.corruptedOrIncomplete = true;
-    } finally {
-      in.close();
-    }
-
-    return info;
-  }
-
-  /**
-   * Loads and parses Blaze profile file, and reports what it is doing.
-   *
-   * @param profileFile profile file path
-   * @param reporter for progress messages and warnings
-   *
-   * @return ProfileInfo object with most fields populated
-   *         (call analyzeRelationships() to populate the remaining fields)
-   * @throws UnsupportedEncodingException if the file format is invalid
-   * @throws IOException if the file can't be read
-   */
-  public static ProfileInfo loadProfileVerbosely(Path profileFile, InfoListener reporter)
-      throws IOException {
-    reporter.info("Loading " + profileFile.getPathString());
-    ProfileInfo profileInfo;
-    try (InputStream in = profileFile.getInputStream()) {
-      profileInfo = ProfileInfo.loadProfile(in);
-    }
-    if (profileInfo.isCorruptedOrIncomplete()) {
-      reporter.warn("Profile file is incomplete or corrupted - not all records were parsed");
-    }
-    reporter.info(profileInfo.comment + ", " + profileInfo.allTasksById.size() + " record(s)");
-    return profileInfo;
-  }
-
-  /*
-   * Sorts and aggregates Blaze profile file, and reports what it is doing.
-   */
-  public static void aggregateProfile(ProfileInfo profileInfo, InfoListener reporter) {
-    reporter.info("Aggregating task statistics");
-    profileInfo.calculateStats();
-  }
-
-}
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/output/PhaseText.java b/src/main/java/com/google/devtools/build/lib/profiler/output/PhaseText.java
index 7472fc0..3a70b21 100644
--- a/src/main/java/com/google/devtools/build/lib/profiler/output/PhaseText.java
+++ b/src/main/java/com/google/devtools/build/lib/profiler/output/PhaseText.java
@@ -13,58 +13,33 @@
 // limitations under the License.
 package com.google.devtools.build.lib.profiler.output;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
 import com.google.devtools.build.lib.profiler.ProfilePhase;
-import com.google.devtools.build.lib.profiler.ProfilerTask;
 import com.google.devtools.build.lib.profiler.statistics.CriticalPathStatistics;
-import com.google.devtools.build.lib.profiler.statistics.PhaseStatistics;
 import com.google.devtools.build.lib.profiler.statistics.PhaseSummaryStatistics;
-import com.google.devtools.build.lib.util.TimeUtilities;
 import java.io.PrintStream;
 import java.time.Duration;
-import java.util.Arrays;
-import java.util.EnumMap;
 
-/** Output {@link PhaseSummaryStatistics} and {@link PhaseStatistics} in text format. */
+/** Output {@link PhaseSummaryStatistics} and {@link CriticalPathStatistics} in text format. */
 public final class PhaseText extends TextPrinter {
 
   private final PhaseSummaryStatistics phaseSummaryStats;
-  private final Optional<EnumMap<ProfilePhase, PhaseStatistics>> phaseStatistics;
-  private final Optional<CriticalPathStatistics> criticalPathStatistics;
+  private final CriticalPathStatistics criticalPathStatistics;
 
   public PhaseText(
       PrintStream out,
       PhaseSummaryStatistics phaseSummaryStats,
-      Optional<EnumMap<ProfilePhase, PhaseStatistics>> phaseStatistics,
-      Optional<CriticalPathStatistics> critPathStats) {
+      CriticalPathStatistics criticalPathStatistics) {
     super(out);
     this.phaseSummaryStats = phaseSummaryStats;
-    this.phaseStatistics = phaseStatistics;
-    this.criticalPathStatistics = critPathStats;
+    this.criticalPathStatistics = criticalPathStatistics;
   }
 
   public void print() {
     printPhaseSummaryStatistics();
 
-    if (phaseStatistics.isPresent()) {
-      for (ProfilePhase phase :
-          Arrays.asList(ProfilePhase.INIT, ProfilePhase.LOAD, ProfilePhase.ANALYZE)) {
-        PhaseStatistics statistics = phaseStatistics.get().get(phase);
-        if (statistics.wasExecuted()) {
-          printPhaseStatistics(statistics);
-        }
-      }
-
-      printExecutionPhaseStatistics();
-    }
-
-    CriticalPathText criticalPaths = null;
-    if (criticalPathStatistics.isPresent()) {
-      criticalPaths = new CriticalPathText(out, criticalPathStatistics.get());
-      criticalPaths.printCriticalPaths();
-      printLn();
-    }
+    CriticalPathText criticalPaths = new CriticalPathText(out, criticalPathStatistics);
+    criticalPaths.printCriticalPaths();
+    printLn();
   }
 
   /**
@@ -92,74 +67,5 @@
         "100.00%");
     printLn();
   }
-
-  /**
-   * Prints all statistics from {@link PhaseStatistics} in text form.
-   */
-  private void printPhaseStatistics(PhaseStatistics stats) {
-    lnPrintf("=== %s PHASE INFORMATION ===\n", stats.getProfilePhase().nick.toUpperCase());
-
-    lnPrintf(
-        TWO_COLUMN_FORMAT,
-        "Total " + stats.getProfilePhase().nick + " phase time",
-        TimeUtilities.prettyTime(stats.getPhaseDurationNanos()));
-    printLn();
-
-    if (!stats.isEmpty()) {
-      printTimingDistribution(stats);
-    }
-  }
-
-  private void printExecutionPhaseStatistics() {
-    Preconditions.checkArgument(phaseStatistics.isPresent());
-    PhaseStatistics prepPhase = phaseStatistics.get().get(ProfilePhase.PREPARE);
-    PhaseStatistics execPhase = phaseStatistics.get().get(ProfilePhase.EXECUTE);
-    PhaseStatistics finishPhase = phaseStatistics.get().get(ProfilePhase.FINISH);
-    if (!execPhase.wasExecuted()) {
-      return;
-    }
-    lnPrint("=== EXECUTION PHASE INFORMATION ===\n");
-
-    long execTime = execPhase.getPhaseDurationNanos();
-
-    if (prepPhase.wasExecuted()) {
-      lnPrintf(
-          TWO_COLUMN_FORMAT,
-          "Total preparation time",
-          TimeUtilities.prettyTime(prepPhase.getPhaseDurationNanos()));
-    }
-    lnPrintf(
-        TWO_COLUMN_FORMAT,
-        "Total execution phase time",
-        TimeUtilities.prettyTime(execPhase.getPhaseDurationNanos()));
-    if (finishPhase.wasExecuted()) {
-      lnPrintf(
-          TWO_COLUMN_FORMAT,
-          "Total time finalizing build",
-          TimeUtilities.prettyTime(finishPhase.getPhaseDurationNanos()));
-    }
-    printLn();
-    lnPrintf(TWO_COLUMN_FORMAT, "Actual execution time", TimeUtilities.prettyTime(execTime));
-
-    printTimingDistribution(execPhase);
-    printLn();
-  }
-
-  /**
-   * Prints a table of task types and their relative total and average execution time as well as
-   * how many tasks of each type there were
-   */
-  private void printTimingDistribution(PhaseStatistics stats) {
-    lnPrint("Total time (across all threads) spent on:");
-    lnPrintf("%18s %8s %8s %11s", "Type", "Total", "Count", "Average");
-    for (ProfilerTask type : stats) {
-      lnPrintf(
-          "%18s %8s %8d %11s",
-          type.toString(),
-          prettyPercentage(stats.getTotalRelativeDuration(type)),
-          stats.getCount(type),
-          TimeUtilities.prettyTime(stats.getMeanDuration(type)));
-    }
-  }
 }
 
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/output/TextPrinter.java b/src/main/java/com/google/devtools/build/lib/profiler/output/TextPrinter.java
index 7e08172..5e428ff 100644
--- a/src/main/java/com/google/devtools/build/lib/profiler/output/TextPrinter.java
+++ b/src/main/java/com/google/devtools/build/lib/profiler/output/TextPrinter.java
@@ -20,7 +20,6 @@
  */
 public abstract class TextPrinter {
 
-  protected static final String TWO_COLUMN_FORMAT = "%-37s %10s";
   protected static final String THREE_COLUMN_FORMAT = "%-28s %10s %8s";
 
   protected final PrintStream out;
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/statistics/CriticalPathStatistics.java b/src/main/java/com/google/devtools/build/lib/profiler/statistics/CriticalPathStatistics.java
index 63e4983..a4b50c7 100644
--- a/src/main/java/com/google/devtools/build/lib/profiler/statistics/CriticalPathStatistics.java
+++ b/src/main/java/com/google/devtools/build/lib/profiler/statistics/CriticalPathStatistics.java
@@ -13,43 +13,20 @@
 // limitations under the License.
 package com.google.devtools.build.lib.profiler.statistics;
 
-import static com.google.devtools.build.lib.profiler.ProfilerTask.CRITICAL_PATH;
-
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.profiler.ProfilerTask;
 import com.google.devtools.build.lib.profiler.TraceEvent;
-import com.google.devtools.build.lib.profiler.analysis.ProfileInfo;
-import com.google.devtools.build.lib.profiler.analysis.ProfileInfo.Task;
 import java.time.Duration;
 import java.util.List;
 
 /**
- * Keeps a predefined list of {@link Task}'s cumulative durations and allows iterating over pairs of
- * their descriptions and relative durations.
+ * Keeps a predefined list of {@link TraceEvent}'s cumulative durations and allows iterating over
+ * pairs of their descriptions and relative durations.
  */
 public final class CriticalPathStatistics {
   private final ImmutableList<TraceEvent> criticalPathEntries;
   private Duration totalDuration = Duration.ZERO;
 
-  public CriticalPathStatistics(ProfileInfo info) {
-    ImmutableList.Builder<TraceEvent> criticalPathEntriesBuilder = new ImmutableList.Builder<>();
-    for (Task task : info.rootTasksById) {
-      if (task.type == CRITICAL_PATH) {
-        for (Task criticalPathEntry : task.subtasks) {
-          totalDuration = totalDuration.plus(Duration.ofNanos(criticalPathEntry.durationNanos));
-          criticalPathEntriesBuilder.add(
-              TraceEvent.create(
-                  ProfilerTask.CRITICAL_PATH_COMPONENT.description,
-                  criticalPathEntry.getDescription(),
-                  Duration.ofNanos(criticalPathEntry.startTime),
-                  Duration.ofNanos(criticalPathEntry.durationNanos),
-                  criticalPathEntry.threadId));
-        }
-      }
-    }
-    this.criticalPathEntries = criticalPathEntriesBuilder.build();
-  }
-
   public CriticalPathStatistics(List<TraceEvent> traceEvents) {
     ImmutableList.Builder<TraceEvent> criticalPathEntriesBuilder = new ImmutableList.Builder<>();
     for (TraceEvent traceEvent : traceEvents) {
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseStatistics.java b/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseStatistics.java
deleted file mode 100644
index 607821b..0000000
--- a/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseStatistics.java
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2015 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.profiler.statistics;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterators;
-import com.google.devtools.build.lib.profiler.ProfilePhase;
-import com.google.devtools.build.lib.profiler.ProfilerTask;
-import com.google.devtools.build.lib.profiler.analysis.ProfileInfo;
-import com.google.devtools.build.lib.profiler.analysis.ProfileInfo.AggregateAttr;
-import com.google.devtools.build.lib.profiler.analysis.ProfileInfo.Task;
-import java.util.EnumMap;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Extracts and keeps statistics for one {@link ProfilePhase} for formatting to various outputs.
- */
-public final class PhaseStatistics implements Iterable<ProfilerTask> {
-
-  private final ProfilePhase phase;
-  private long phaseDurationNanos;
-  private long totalDurationNanos;
-  private final EnumMap<ProfilerTask, Long> taskDurations;
-  private final EnumMap<ProfilerTask, Long> taskCounts;
-  private boolean wasExecuted;
-
-  public PhaseStatistics(ProfilePhase phase) {
-    this.phase = phase;
-    this.taskDurations = new EnumMap<>(ProfilerTask.class);
-    this.taskCounts = new EnumMap<>(ProfilerTask.class);
-  }
-
-  public PhaseStatistics(ProfilePhase phase, ProfileInfo info) {
-    this(phase);
-    addProfileInfo(info);
-  }
-
-  /** Add statistics from {@link ProfileInfo} to the ones already accumulated for this phase. */
-  public void addProfileInfo(ProfileInfo info) {
-    Task phaseTask = info.getPhaseTask(phase);
-    if (phaseTask != null) {
-      wasExecuted = true;
-      long infoPhaseDuration = info.getPhaseDuration(phaseTask);
-      phaseDurationNanos += infoPhaseDuration;
-      List<Task> taskList = info.getTasksForPhase(phaseTask);
-      long duration = infoPhaseDuration;
-      for (Task task : taskList) {
-        // Tasks on the phaseTask thread already accounted for in the phaseDuration.
-        if (task.threadId != phaseTask.threadId) {
-          duration += task.durationNanos;
-        }
-      }
-      totalDurationNanos += duration;
-      for (ProfilerTask type : ProfilerTask.values()) {
-        AggregateAttr attr = info.getStatsForType(type, taskList);
-        long totalTime = Math.max(0, attr.totalTime);
-        long count = Math.max(0, attr.count);
-        add(taskCounts, type, count);
-        add(taskDurations, type, totalTime);
-      }
-    }
-  }
-
-  /** Helper method to sum up long values within an {@link EnumMap}. */
-  private static <T extends Enum<T>> void add(EnumMap<T, Long> map, T key, long value) {
-    long previous;
-    if (map.containsKey(key)) {
-      previous = map.get(key);
-    } else {
-      previous = 0;
-    }
-    map.put(key, previous + value);
-  }
-
-  public ProfilePhase getProfilePhase() {
-    return phase;
-  }
-
-  /**
-   * @return true if no {@link ProfilerTask}s have been executed in this phase, false otherwise
-   */
-  public boolean isEmpty() {
-    return taskCounts.isEmpty();
-  }
-
-  /** @return true if the phase was not executed at all, false otherwise */
-  public boolean wasExecuted() {
-    return wasExecuted;
-  }
-
-  /** @return true if a task of the given {@link ProfilerTask} type was executed in this phase */
-  public boolean wasExecuted(ProfilerTask taskType) {
-    Long count = taskCounts.get(taskType);
-    return count != null && count != 0;
-  }
-
-  public long getPhaseDurationNanos() {
-    return phaseDurationNanos;
-  }
-
-  /** @return the sum of all task durations of the given type */
-  public long getTotalDurationNanos(ProfilerTask taskType) {
-    Long duration = taskDurations.get(taskType);
-    if (duration == null) {
-      return 0;
-    }
-    return duration;
-  }
-
-  /**
-   * @return the average duration of all {@link ProfilerTask}
-   */
-  public double getMeanDuration(ProfilerTask taskType) {
-    if (wasExecuted(taskType)) {
-      double duration = taskDurations.get(taskType);
-      long count = taskCounts.get(taskType);
-      return duration / count;
-    }
-    return 0;
-  }
-
-  /**
-   * @return the duration of all {@link ProfilerTask} executed in the phase relative to the total
-   *    phase duration
-   */
-  public double getTotalRelativeDuration(ProfilerTask taskType) {
-    Long duration = taskDurations.get(taskType);
-    if (duration == null || duration == 0) {
-      return 0;
-    }
-    // sanity check for broken profile files
-    Preconditions.checkState(
-        totalDurationNanos != 0,
-        "Profiler tasks of type %s have non-zero duration %s in phase %s but the phase itself has"
-        + " zero duration. Most likely the profile file is broken.",
-        taskType,
-        duration,
-        phase);
-    return (double) duration / totalDurationNanos;
-  }
-
-  /**
-   * @return how many tasks of the given type were executed in this phase
-   */
-  public long getCount(ProfilerTask taskType) {
-    Long count = taskCounts.get(taskType);
-    if (count == null) {
-      return 0;
-    }
-    return count;
-  }
-
-  /**
-   * Iterator over all {@link ProfilerTask}s that were executed at least once and have a total
-   * duration greater than 0.
-   */
-  @Override
-  public Iterator<ProfilerTask> iterator() {
-    return Iterators.filter(
-        taskCounts.keySet().iterator(),
-        taskType -> getTotalDurationNanos(taskType) > 0 && wasExecuted(taskType));
-  }
-}
-
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java b/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java
index 2ce3025..8352b55 100644
--- a/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java
+++ b/src/main/java/com/google/devtools/build/lib/profiler/statistics/PhaseSummaryStatistics.java
@@ -14,7 +14,6 @@
 package com.google.devtools.build.lib.profiler.statistics;
 
 import com.google.devtools.build.lib.profiler.ProfilePhase;
-import com.google.devtools.build.lib.profiler.analysis.ProfileInfo;
 import java.time.Duration;
 import java.util.EnumMap;
 import java.util.Iterator;
@@ -34,23 +33,6 @@
     totalDurationNanos = 0;
   }
 
-  public PhaseSummaryStatistics(ProfileInfo info) {
-    this();
-    addProfileInfo(info);
-  }
-
-  /** Add a summary of the {@link ProfilePhase}s durations from a {@link ProfileInfo}. */
-  private void addProfileInfo(ProfileInfo info) {
-    for (ProfilePhase phase : ProfilePhase.values()) {
-      ProfileInfo.Task phaseTask = info.getPhaseTask(phase);
-      if (phaseTask != null) {
-        long phaseDuration = info.getPhaseDuration(phaseTask);
-        totalDurationNanos += phaseDuration;
-        durations.put(phase, phaseDuration);
-      }
-    }
-  }
-
   /** Add a single profile phase. */
   public void addProfilePhase(ProfilePhase phase, Duration duration) {
     totalDurationNanos += duration.toNanos();
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/ProfileCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/ProfileCommand.java
index 9b27c6d..310a199 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/ProfileCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/ProfileCommand.java
@@ -13,27 +13,16 @@
 // limitations under the License.
 package com.google.devtools.build.lib.runtime.commands;
 
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
 import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.events.Reporter;
 import com.google.devtools.build.lib.profiler.JsonProfile;
-import com.google.devtools.build.lib.profiler.ProfilePhase;
-import com.google.devtools.build.lib.profiler.ProfilerTask;
-import com.google.devtools.build.lib.profiler.analysis.ProfileInfo;
-import com.google.devtools.build.lib.profiler.analysis.ProfileInfo.InfoListener;
 import com.google.devtools.build.lib.profiler.output.PhaseText;
 import com.google.devtools.build.lib.profiler.statistics.CriticalPathStatistics;
-import com.google.devtools.build.lib.profiler.statistics.PhaseStatistics;
-import com.google.devtools.build.lib.profiler.statistics.PhaseSummaryStatistics;
 import com.google.devtools.build.lib.runtime.BlazeCommand;
 import com.google.devtools.build.lib.runtime.BlazeCommandResult;
 import com.google.devtools.build.lib.runtime.Command;
 import com.google.devtools.build.lib.runtime.CommandEnvironment;
 import com.google.devtools.build.lib.util.ExitCode;
-import com.google.devtools.build.lib.util.StringUtil;
-import com.google.devtools.build.lib.util.TimeUtilities;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.common.options.Converters;
 import com.google.devtools.common.options.Option;
@@ -47,7 +36,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
-import java.util.EnumMap;
 
 /** Command line wrapper for analyzing Blaze build profiles. */
 @Command(
@@ -81,22 +69,6 @@
     public String dumpMode;
   }
 
-  private InfoListener getInfoListener(final CommandEnvironment env) {
-    return new InfoListener() {
-      private final EventHandler reporter = env.getReporter();
-
-      @Override
-      public void info(String text) {
-        reporter.handle(Event.info(text));
-      }
-
-      @Override
-      public void warn(String text) {
-        reporter.handle(Event.warn(text));
-      }
-    };
-  }
-
   /**
    * Note that this is just a basic check whether the file is zlib compressed.
    *
@@ -126,7 +98,6 @@
 
     try (PrintStream out = getOutputStream(env)) {
       Reporter reporter = env.getReporter();
-      InfoListener infoListener = getInfoListener(env);
 
       reporter.handle(
           Event.warn(
@@ -135,15 +106,11 @@
       for (String name : options.getResidue()) {
         Path profileFile = env.getWorkingDirectory().getRelative(name);
         if (isOldBinaryProfile(profileFile.getPathFile())) {
-          BlazeCommandResult commandResult =
-              handleOldBinaryProfile(env, dumpMode, out, profileFile, infoListener);
-          if (commandResult != null) {
-            return commandResult;
-          }
           reporter.handle(
-              Event.warn(
+              Event.error(
                   "The old binary profile format is deprecated."
                       + " Use the JSON trace profile instead."));
+          return BlazeCommandResult.exitCode(ExitCode.PARSING_FAILURE);
         } else {
           try {
             if (dumpMode != null) {
@@ -155,20 +122,20 @@
 
             JsonProfile.BuildMetadata buildMetadata = jsonProfile.getBuildMetadata();
             if (buildMetadata != null) {
-              infoListener.info(
-                  "Profile created on "
-                      + buildMetadata.date()
-                      + ", build ID: "
-                      + buildMetadata.buildId()
-                      + ", output base: "
-                      + buildMetadata.outputBase());
+              reporter.handle(
+                  Event.info(
+                      "Profile created on "
+                          + buildMetadata.date()
+                          + ", build ID: "
+                          + buildMetadata.buildId()
+                          + ", output base: "
+                          + buildMetadata.outputBase()));
             }
 
             new PhaseText(
                     out,
                     jsonProfile.getPhaseSummaryStatistics(),
-                    /* phaseStatistics= */ Optional.absent(),
-                    Optional.of(new CriticalPathStatistics(jsonProfile.getTraceEvents())))
+                    new CriticalPathStatistics(jsonProfile.getTraceEvents()))
                 .print();
           } catch (IOException e) {
             reporter.handle(Event.error("Failed to analyze profile file(s): " + e.getMessage()));
@@ -180,116 +147,8 @@
     return BlazeCommandResult.exitCode(ExitCode.SUCCESS);
   }
 
-  private static BlazeCommandResult handleOldBinaryProfile(
-      CommandEnvironment env,
-      String dumpMode,
-      PrintStream out,
-      Path profileFile,
-      InfoListener infoListener) {
-    try {
-      ProfileInfo info = ProfileInfo.loadProfileVerbosely(profileFile, infoListener);
-
-      if (dumpMode != null) {
-        dumpProfile(info, out, dumpMode);
-        return null;
-      }
-
-      ProfileInfo.aggregateProfile(info, infoListener);
-      PhaseSummaryStatistics phaseSummaryStatistics = new PhaseSummaryStatistics(info);
-      EnumMap<ProfilePhase, PhaseStatistics> phaseStatistics = new EnumMap<>(ProfilePhase.class);
-
-      for (ProfilePhase phase : ProfilePhase.values()) {
-        phaseStatistics.put(phase, new PhaseStatistics(phase, info));
-      }
-
-      new PhaseText(
-              out,
-              phaseSummaryStatistics,
-              Optional.of(phaseStatistics),
-              Optional.of(new CriticalPathStatistics(info)))
-          .print();
-    } catch (IOException e) {
-      System.out.println(e);
-      env.getReporter().handle(Event.error("Failed to analyze profile file(s): " + e.getMessage()));
-      return BlazeCommandResult.exitCode(ExitCode.PARSING_FAILURE);
-    }
-    return null;
-  }
-
   private static PrintStream getOutputStream(CommandEnvironment env) {
     return new PrintStream(
         new BufferedOutputStream(env.getReporter().getOutErr().getOutputStream()), false);
   }
-
-  /** Dumps all tasks in the requested format. */
-  private static void dumpProfile(ProfileInfo info, PrintStream out, String dumpMode) {
-    if (dumpMode.contains("raw")) {
-      for (ProfileInfo.Task task : info.allTasksById) {
-        dumpRaw(task, out);
-      }
-    } else {
-      for (ProfileInfo.Task task : info.rootTasksById) {
-        dumpTask(task, out, 0);
-      }
-    }
-  }
-
-  /** Dumps the task information and all subtasks. */
-  private static void dumpTask(ProfileInfo.Task task, PrintStream out, int indent) {
-    StringBuilder builder =
-        new StringBuilder(
-            String.format(
-                Joiner.on('\n')
-                    .join(
-                        "",
-                        "%s %s",
-                        "Thread: %-6d  Id: %-6d  Parent: %d",
-                        "Start time: %-12s   Duration: %s"),
-                task.type,
-                task.getDescription(),
-                task.threadId,
-                task.id,
-                task.parentId,
-                TimeUtilities.prettyTime(task.startTime),
-                TimeUtilities.prettyTime(task.durationNanos)));
-    if (task.hasStats()) {
-      builder.append("\n");
-      ProfileInfo.AggregateAttr[] stats = task.getStatAttrArray();
-      for (ProfilerTask type : ProfilerTask.values()) {
-        ProfileInfo.AggregateAttr attr = stats[type.ordinal()];
-        if (attr != null) {
-          builder.append(type.toString().toLowerCase()).append("=(").
-              append(attr.count).append(", ").
-              append(TimeUtilities.prettyTime(attr.totalTime)).append(") ");
-        }
-      }
-    }
-    out.println(StringUtil.indent(builder.toString(), indent));
-    for (ProfileInfo.Task subtask : task.subtasks) {
-      dumpTask(subtask, out, indent + 1);
-    }
-  }
-
-  private static void dumpRaw(ProfileInfo.Task task, PrintStream out) {
-    StringBuilder aggregateString = new StringBuilder();
-    ProfileInfo.AggregateAttr[] stats = task.getStatAttrArray();
-    for (ProfilerTask type : ProfilerTask.values()) {
-      ProfileInfo.AggregateAttr attr = stats[type.ordinal()];
-      if (attr != null) {
-        aggregateString.append(type.toString().toLowerCase()).append(",").
-            append(attr.count).append(",").append(attr.totalTime).append(" ");
-      }
-    }
-    out.println(
-        Joiner.on('|')
-            .join(
-                task.threadId,
-                task.id,
-                task.parentId,
-                task.startTime,
-                task.durationNanos,
-                aggregateString.toString().trim(),
-                task.type,
-                task.getDescription()));
-  }
 }