struct perf_session     *session;
        const char              *file;
        int                      idx;
+       struct hists            *hists;
        struct diff_hpp_fmt      fmt[PERF_HPP_DIFF__MAX_INDEX];
 };
 
             i++, d = &data__files[i])
 
 #define data__for_each_file(i, d) data__for_each_file_start(i, d, 0)
+#define data__for_each_file_new(i, d) data__for_each_file_start(i, d, 1)
 
 static char diff__default_sort_order[] = "dso,symbol";
 static bool force;
        }
 }
 
-static void hists__process(struct hists *base, struct hists *new)
+static void hists__process(struct hists *hists)
 {
-       hists__match(base, new);
-
        if (show_baseline_only)
-               hists__baseline_only(base);
-       else
-               hists__link(base, new);
+               hists__baseline_only(hists);
 
        if (sort_compute) {
-               hists__precompute(base);
-               hists__compute_resort(base);
+               hists__precompute(hists);
+               hists__compute_resort(hists);
        } else {
-               hists__output_resort(base);
+               hists__output_resort(hists);
        }
 
-       hists__fprintf(base, true, 0, 0, 0, stdout);
+       hists__fprintf(hists, true, 0, 0, 0, stdout);
 }
 
 static void data__fprintf(void)
 
 static void data_process(void)
 {
-       struct perf_evlist *evlist_old = data__files[0].session->evlist;
-       struct perf_evlist *evlist_new = data__files[1].session->evlist;
-       struct perf_evsel *evsel_old;
+       struct perf_evlist *evlist_base = data__files[0].session->evlist;
+       struct perf_evsel *evsel_base;
        bool first = true;
 
-       list_for_each_entry(evsel_old, &evlist_old->entries, node) {
-               struct perf_evsel *evsel_new;
+       list_for_each_entry(evsel_base, &evlist_base->entries, node) {
+               struct data__file *d;
+               int i;
 
-               evsel_new = evsel_match(evsel_old, evlist_new);
-               if (!evsel_new)
-                       continue;
+               data__for_each_file_new(i, d) {
+                       struct perf_evlist *evlist = d->session->evlist;
+                       struct perf_evsel *evsel;
+
+                       evsel = evsel_match(evsel_base, evlist);
+                       if (!evsel)
+                               continue;
+
+                       d->hists = &evsel->hists;
+
+                       hists__match(&evsel_base->hists, &evsel->hists);
+
+                       if (!show_baseline_only)
+                               hists__link(&evsel_base->hists,
+                                           &evsel->hists);
+               }
 
                fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
-                       perf_evsel__name(evsel_old));
+                       perf_evsel__name(evsel_base));
 
                first = false;
 
-               if (verbose)
+               if (verbose || data__files_cnt > 2)
                        data__fprintf();
 
-               hists__process(&evsel_old->hists, &evsel_new->hists);
+               hists__process(&evsel_base->hists);
        }
 }
 
        };
 }
 
+static struct hist_entry *get_pair(struct hist_entry *he,
+                                  struct diff_hpp_fmt *dfmt)
+{
+       void *ptr = dfmt - dfmt->idx;
+       struct data__file *d = container_of(ptr, struct data__file, fmt);
+
+       if (hist_entry__has_pairs(he)) {
+               struct hist_entry *pair;
+
+               list_for_each_entry(pair, &he->pairs.head, pairs.node)
+                       if (pair->hists == d->hists)
+                               return pair;
+       }
+
+       return NULL;
+}
+
 static void
-__hpp__entry_global(struct hist_entry *he, int idx, char *buf, size_t size)
+__hpp__entry_global(struct hist_entry *he, struct diff_hpp_fmt *dfmt,
+                   char *buf, size_t size)
 {
-       struct hist_entry *pair = hist_entry__next_pair(he);
+       struct hist_entry *pair = get_pair(he, dfmt);
+       int idx = dfmt->idx;
 
        /* baseline is special */
        if (idx == PERF_HPP_DIFF__BASELINE)
                container_of(_fmt, struct diff_hpp_fmt, fmt);
        char buf[MAX_COL_WIDTH] = " ";
 
-       __hpp__entry_global(he, dfmt->idx, buf, MAX_COL_WIDTH);
+       __hpp__entry_global(he, dfmt, buf, MAX_COL_WIDTH);
 
        if (symbol_conf.field_sep)
                return scnprintf(hpp->buf, hpp->size, "%s", buf);
        return dfmt->header_width;
 }
 
-static void init_header(struct diff_hpp_fmt *dfmt)
+static void init_header(struct data__file *d, struct diff_hpp_fmt *dfmt)
 {
 #define MAX_HEADER_NAME 100
        char buf_indent[MAX_HEADER_NAME];
        /* Only our defined HPP fmts should appear here. */
        BUG_ON(!header);
 
+       if (data__files_cnt > 2)
+               scnprintf(buf, MAX_HEADER_NAME, "%s/%d", header, d->idx);
+
 #define NAME (data__files_cnt > 2 ? buf : header)
        dfmt->header_width = width;
        width = (int) strlen(NAME);
        if (idx == PERF_HPP_DIFF__BASELINE)
                fmt->color = hpp__color_baseline;
 
-       init_header(dfmt);
+       init_header(d, dfmt);
        perf_hpp__column_register(fmt);
 }
 
                "perf.data.old",
                "perf.data",
        };
+       bool use_default = true;
        int i;
 
        data__files_cnt = 2;
 
        if (argc) {
-               if (argc > 2)
-                       usage_with_options(diff_usage, options);
-               if (argc == 2) {
-                       defaults[0] = argv[0];
-                       defaults[1] = argv[1];
-               } else
+               if (argc == 1)
                        defaults[1] = argv[0];
+               else {
+                       data__files_cnt = argc;
+                       use_default = false;
+               }
        } else if (symbol_conf.default_guest_vmlinux_name ||
                   symbol_conf.default_guest_kallsyms) {
                defaults[0] = "perf.data.host";
                return -ENOMEM;
 
        data__for_each_file(i, d) {
-               d->file = defaults[i];
+               d->file = use_default ? defaults[i] : argv[i];
                d->idx  = i;
        }