return hist_entry__append_callchain(he, sample);
 }
 
+static int
+iter_prepare_cumulative_entry(struct hist_entry_iter *iter __maybe_unused,
+                             struct addr_location *al __maybe_unused)
+{
+       callchain_cursor_commit(&callchain_cursor);
+       return 0;
+}
+
+static int
+iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
+                                struct addr_location *al)
+{
+       struct perf_evsel *evsel = iter->evsel;
+       struct perf_sample *sample = iter->sample;
+       struct hist_entry *he;
+       int err = 0;
+
+       he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
+                               sample->period, sample->weight,
+                               sample->transaction, true);
+       if (he == NULL)
+               return -ENOMEM;
+
+       iter->he = he;
+
+       /*
+        * The iter->he will be over-written after ->add_next_entry()
+        * called so inc stats for the original entry now.
+        */
+       if (ui__has_annotation())
+               err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
+
+       hists__inc_nr_samples(&evsel->hists, he->filtered);
+
+       return err;
+}
+
+static int
+iter_next_cumulative_entry(struct hist_entry_iter *iter,
+                          struct addr_location *al)
+{
+       struct callchain_cursor_node *node;
+
+       node = callchain_cursor_current(&callchain_cursor);
+       if (node == NULL)
+               return 0;
+
+       al->map = node->map;
+       al->sym = node->sym;
+       if (node->map)
+               al->addr = node->map->map_ip(node->map, node->ip);
+       else
+               al->addr = node->ip;
+
+       if (iter->hide_unresolved && al->sym == NULL)
+               return 0;
+
+       callchain_cursor_advance(&callchain_cursor);
+       return 1;
+}
+
+static int
+iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
+                              struct addr_location *al)
+{
+       struct perf_evsel *evsel = iter->evsel;
+       struct perf_sample *sample = iter->sample;
+       struct hist_entry *he;
+
+       he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
+                               sample->period, sample->weight,
+                               sample->transaction, false);
+       if (he == NULL)
+               return -ENOMEM;
+
+       iter->he = he;
+
+       return 0;
+}
+
+static int
+iter_finish_cumulative_entry(struct hist_entry_iter *iter,
+                            struct addr_location *al __maybe_unused)
+{
+       iter->he = NULL;
+       return 0;
+}
+
 const struct hist_iter_ops hist_iter_mem = {
        .prepare_entry          = iter_prepare_mem_entry,
        .add_single_entry       = iter_add_single_mem_entry,
        .finish_entry           = iter_finish_normal_entry,
 };
 
+const struct hist_iter_ops hist_iter_cumulative = {
+       .prepare_entry          = iter_prepare_cumulative_entry,
+       .add_single_entry       = iter_add_single_cumulative_entry,
+       .next_entry             = iter_next_cumulative_entry,
+       .add_next_entry         = iter_add_next_cumulative_entry,
+       .finish_entry           = iter_finish_cumulative_entry,
+};
+
 int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
                         struct perf_evsel *evsel, struct perf_sample *sample,
                         int max_stack_depth)