#include <linux/types.h>
 #include <sys/prctl.h>
 #include <perf/cpumap.h>
+#include <perf/evlist.h>
 
 #include "parse-events.h"
 #include "evlist.h"
        evlist = evlist__new();
        CHECK_NOT_NULL__(evlist);
 
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
 
        CHECK__(parse_events(evlist, "cycles:u", NULL));
 
 
 #include <fcntl.h>
 #include <unistd.h>
 #include <subcmd/pager.h>
+#include <perf/evlist.h>
 
 #include <linux/ctype.h>
 
        if (WARN_ONCE(script->allocated, "stats double allocation\n"))
                return -EINVAL;
 
-       perf_evlist__set_maps(evlist, script->cpus, script->threads);
+       perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
 
        if (perf_evlist__alloc_stats(evlist, true))
                return -ENOMEM;
 
 #include <sys/resource.h>
 
 #include <linux/ctype.h>
+#include <perf/evlist.h>
 
 #define DEFAULT_SEPARATOR      " "
 #define FREEZE_ON_SMI_PATH     "devices/cpu/freeze_on_smi"
        if (WARN_ONCE(st->maps_allocated, "stats double allocation\n"))
                return -EINVAL;
 
-       perf_evlist__set_maps(evsel_list, st->cpus, st->threads);
+       perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads);
 
        if (perf_evlist__alloc_stats(evsel_list, true))
                return -ENOMEM;
 
 #include <internal/evsel.h>
 #include <linux/zalloc.h>
 #include <stdlib.h>
+#include <perf/cpumap.h>
+#include <perf/threadmap.h>
 
 void perf_evlist__init(struct perf_evlist *evlist)
 {
        evlist->nr_entries = 0;
 }
 
+static void __perf_evlist__propagate_maps(struct perf_evlist *evlist,
+                                         struct perf_evsel *evsel)
+{
+       /*
+        * We already have cpus for evsel (via PMU sysfs) so
+        * keep it, if there's no target cpu list defined.
+        */
+       if (!evsel->own_cpus || evlist->has_user_cpus) {
+               perf_cpu_map__put(evsel->cpus);
+               evsel->cpus = perf_cpu_map__get(evlist->cpus);
+       } else if (evsel->cpus != evsel->own_cpus) {
+               perf_cpu_map__put(evsel->cpus);
+               evsel->cpus = perf_cpu_map__get(evsel->own_cpus);
+       }
+
+       perf_thread_map__put(evsel->threads);
+       evsel->threads = perf_thread_map__get(evlist->threads);
+}
+
+static void perf_evlist__propagate_maps(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel;
+
+       perf_evlist__for_each_evsel(evlist, evsel)
+               __perf_evlist__propagate_maps(evlist, evsel);
+}
+
 void perf_evlist__add(struct perf_evlist *evlist,
                      struct perf_evsel *evsel)
 {
        list_add_tail(&evsel->node, &evlist->entries);
        evlist->nr_entries += 1;
+       __perf_evlist__propagate_maps(evlist, evsel);
 }
 
 void perf_evlist__remove(struct perf_evlist *evlist,
 {
        free(evlist);
 }
+
+void perf_evlist__set_maps(struct perf_evlist *evlist,
+                          struct perf_cpu_map *cpus,
+                          struct perf_thread_map *threads)
+{
+       /*
+        * Allow for the possibility that one or another of the maps isn't being
+        * changed i.e. don't put it.  Note we are assuming the maps that are
+        * being applied are brand new and evlist is taking ownership of the
+        * original reference count of 1.  If that is not the case it is up to
+        * the caller to increase the reference count.
+        */
+       if (cpus != evlist->cpus) {
+               perf_cpu_map__put(evlist->cpus);
+               evlist->cpus = perf_cpu_map__get(cpus);
+       }
+
+       if (threads != evlist->threads) {
+               perf_thread_map__put(evlist->threads);
+               evlist->threads = perf_thread_map__get(threads);
+       }
+
+       perf_evlist__propagate_maps(evlist);
+}
 
 
 struct perf_evlist;
 struct perf_evsel;
+struct perf_cpu_map;
+struct perf_thread_map;
 
 LIBPERF_API void perf_evlist__init(struct perf_evlist *evlist);
 LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist,
             (pos) != NULL;                             \
             (pos) = perf_evlist__next((evlist), (pos)))
 
+LIBPERF_API void perf_evlist__set_maps(struct perf_evlist *evlist,
+                                      struct perf_cpu_map *cpus,
+                                      struct perf_thread_map *threads);
+
 #endif /* __LIBPERF_EVLIST_H */
 
                perf_evlist__add;
                perf_evlist__remove;
                perf_evlist__next;
+               perf_evlist__set_maps;
        local:
                *;
 };
 
 #include <string.h>
 #include <sys/param.h>
 #include <perf/cpumap.h>
+#include <perf/evlist.h>
 
 #include "parse-events.h"
 #include "evlist.h"
                        goto out_put;
                }
 
-               perf_evlist__set_maps(evlist, cpus, threads);
+               perf_evlist__set_maps(&evlist->core, cpus, threads);
 
                str = do_determine_event(excl_kernel);
                pr_debug("Parsing event '%s'\n", str);
                                 */
                                perf_cpu_map__get(cpus);
                                perf_thread_map__get(threads);
-                               perf_evlist__set_maps(evlist, NULL, NULL);
+                               perf_evlist__set_maps(&evlist->core, NULL, NULL);
                                evlist__delete(evlist);
                                evlist = NULL;
                                continue;
 
 #include <unistd.h>
 #include <sys/prctl.h>
 #include <perf/cpumap.h>
+#include <perf/evlist.h>
 
 #include "parse-events.h"
 #include "evlist.h"
        evlist = evlist__new();
        CHECK_NOT_NULL__(evlist);
 
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
 
        CHECK__(parse_events(evlist, "dummy:u", NULL));
        CHECK__(parse_events(evlist, "cycles:u", NULL));
 
 #include "tests.h"
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <perf/evlist.h>
 
 /*
  * This test will generate random numbers of calls to some getpid syscalls,
                goto out_free_cpus;
        }
 
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
 
        for (i = 0; i < nsyscalls; ++i) {
                char name[64];
 
 #include "util/evlist.h"
 #include "util/cpumap.h"
 #include "util/thread_map.h"
+#include <perf/evlist.h>
 
 #define NR_LOOPS  10000000
 
                goto out_free_maps;
        }
 
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
 
        cpus    = NULL;
        threads = NULL;
 
 #include <stdlib.h>
 #include <linux/zalloc.h>
 #include <perf/cpumap.h>
+#include <perf/evlist.h>
 
 #include "parse-events.h"
 #include "evlist.h"
                goto out_err;
        }
 
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
 
        /* First event */
        err = parse_events(evlist, "cpu-clock:u", NULL);
 
 
 #include <errno.h>
 #include <signal.h>
+#include <perf/evlist.h>
 
 static int exited;
 static int nr_exit;
                goto out_free_maps;
        }
 
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
 
        cpus    = NULL;
        threads = NULL;
 
        for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
                INIT_HLIST_HEAD(&evlist->heads[i]);
        perf_evlist__init(&evlist->core);
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
        fdarray__init(&evlist->pollfd, 64);
        evlist->workload.pid = -1;
        evlist->bkw_mmap_state = BKW_MMAP_NOTREADY;
        free(evlist);
 }
 
-static void __perf_evlist__propagate_maps(struct evlist *evlist,
-                                         struct evsel *evsel)
-{
-       /*
-        * We already have cpus for evsel (via PMU sysfs) so
-        * keep it, if there's no target cpu list defined.
-        */
-       if (!evsel->core.own_cpus || evlist->core.has_user_cpus) {
-               perf_cpu_map__put(evsel->core.cpus);
-               evsel->core.cpus = perf_cpu_map__get(evlist->core.cpus);
-       } else if (evsel->core.cpus != evsel->core.own_cpus) {
-               perf_cpu_map__put(evsel->core.cpus);
-               evsel->core.cpus = perf_cpu_map__get(evsel->core.own_cpus);
-       }
-
-       perf_thread_map__put(evsel->core.threads);
-       evsel->core.threads = perf_thread_map__get(evlist->core.threads);
-}
-
-static void perf_evlist__propagate_maps(struct evlist *evlist)
-{
-       struct evsel *evsel;
-
-       evlist__for_each_entry(evlist, evsel)
-               __perf_evlist__propagate_maps(evlist, evsel);
-}
-
 void evlist__add(struct evlist *evlist, struct evsel *entry)
 {
        entry->evlist = evlist;
 
        if (evlist->core.nr_entries == 1)
                perf_evlist__set_id_pos(evlist);
-
-       __perf_evlist__propagate_maps(evlist, entry);
 }
 
 void evlist__remove(struct evlist *evlist, struct evsel *evsel)
 
        evlist->core.has_user_cpus = !!target->cpu_list;
 
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
 
        return 0;
 
        return -1;
 }
 
-void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus,
-                          struct perf_thread_map *threads)
-{
-       /*
-        * Allow for the possibility that one or another of the maps isn't being
-        * changed i.e. don't put it.  Note we are assuming the maps that are
-        * being applied are brand new and evlist is taking ownership of the
-        * original reference count of 1.  If that is not the case it is up to
-        * the caller to increase the reference count.
-        */
-       if (cpus != evlist->core.cpus) {
-               perf_cpu_map__put(evlist->core.cpus);
-               evlist->core.cpus = perf_cpu_map__get(cpus);
-       }
-
-       if (threads != evlist->core.threads) {
-               perf_thread_map__put(evlist->core.threads);
-               evlist->core.threads = perf_thread_map__get(threads);
-       }
-
-       perf_evlist__propagate_maps(evlist);
-}
-
 void __perf_evlist__set_sample_bit(struct evlist *evlist,
                                   enum perf_event_sample_format bit)
 {
        if (!threads)
                goto out_put;
 
-       perf_evlist__set_maps(evlist, cpus, threads);
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
 out:
        return err;
 out_put:
 
 void perf_evlist__set_selected(struct evlist *evlist,
                               struct evsel *evsel);
 
-void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus,
-                          struct perf_thread_map *threads);
 int perf_evlist__create_maps(struct evlist *evlist, struct target *target);
 int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel);