Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[linux-2.6-microblaze.git] / tools / perf / builtin-annotate.c
index 3956ea1..6c1cc79 100644 (file)
@@ -57,6 +57,8 @@ struct perf_annotate {
        bool       has_br_stack;
        bool       group_set;
        bool       data_type;
+       bool       type_stat;
+       bool       insn_stat;
        float      min_percent;
        const char *sym_hist_filter;
        const char *cpu_list;
@@ -396,6 +398,79 @@ static void print_annotated_data_type(struct annotated_data_type *mem_type,
        printf(";\n");
 }
 
+static void print_annotate_data_stat(struct annotated_data_stat *s)
+{
+#define PRINT_STAT(fld) if (s->fld) printf("%10d : %s\n", s->fld, #fld)
+
+       int bad = s->no_sym +
+                       s->no_insn +
+                       s->no_insn_ops +
+                       s->no_mem_ops +
+                       s->no_reg +
+                       s->no_dbginfo +
+                       s->no_cuinfo +
+                       s->no_var +
+                       s->no_typeinfo +
+                       s->invalid_size +
+                       s->bad_offset;
+       int ok = s->total - bad;
+
+       printf("Annotate data type stats:\n");
+       printf("total %d, ok %d (%.1f%%), bad %d (%.1f%%)\n",
+               s->total, ok, 100.0 * ok / (s->total ?: 1), bad, 100.0 * bad / (s->total ?: 1));
+       printf("-----------------------------------------------------------\n");
+       PRINT_STAT(no_sym);
+       PRINT_STAT(no_insn);
+       PRINT_STAT(no_insn_ops);
+       PRINT_STAT(no_mem_ops);
+       PRINT_STAT(no_reg);
+       PRINT_STAT(no_dbginfo);
+       PRINT_STAT(no_cuinfo);
+       PRINT_STAT(no_var);
+       PRINT_STAT(no_typeinfo);
+       PRINT_STAT(invalid_size);
+       PRINT_STAT(bad_offset);
+       printf("\n");
+
+#undef PRINT_STAT
+}
+
+static void print_annotate_item_stat(struct list_head *head, const char *title)
+{
+       struct annotated_item_stat *istat, *pos, *iter;
+       int total_good, total_bad, total;
+       int sum1, sum2;
+       LIST_HEAD(tmp);
+
+       /* sort the list by count */
+       list_splice_init(head, &tmp);
+       total_good = total_bad = 0;
+
+       list_for_each_entry_safe(istat, pos, &tmp, list) {
+               total_good += istat->good;
+               total_bad += istat->bad;
+               sum1 = istat->good + istat->bad;
+
+               list_for_each_entry(iter, head, list) {
+                       sum2 = iter->good + iter->bad;
+                       if (sum1 > sum2)
+                               break;
+               }
+               list_move_tail(&istat->list, &iter->list);
+       }
+       total = total_good + total_bad;
+
+       printf("Annotate %s stats\n", title);
+       printf("total %d, ok %d (%.1f%%), bad %d (%.1f%%)\n\n", total,
+              total_good, 100.0 * total_good / (total ?: 1),
+              total_bad, 100.0 * total_bad / (total ?: 1));
+       printf("  %-10s: %5s %5s\n", "Name", "Good", "Bad");
+       printf("-----------------------------------------------------------\n");
+       list_for_each_entry(istat, head, list)
+               printf("  %-10s: %5d %5d\n", istat->name, istat->good, istat->bad);
+       printf("\n");
+}
+
 static void hists__find_annotations(struct hists *hists,
                                    struct evsel *evsel,
                                    struct perf_annotate *ann)
@@ -403,6 +478,11 @@ static void hists__find_annotations(struct hists *hists,
        struct rb_node *nd = rb_first_cached(&hists->entries), *next;
        int key = K_RIGHT;
 
+       if (ann->type_stat)
+               print_annotate_data_stat(&ann_data_stat);
+       if (ann->insn_stat)
+               print_annotate_item_stat(&ann_insn_stat, "Instruction");
+
        while (nd) {
                struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
                struct annotation *notes;
@@ -749,7 +829,10 @@ int cmd_annotate(int argc, const char **argv)
        OPT_CALLBACK_OPTARG(0, "data-type", &annotate, NULL, "name",
                            "Show data type annotate for the memory accesses",
                            parse_data_type),
-
+       OPT_BOOLEAN(0, "type-stat", &annotate.type_stat,
+                   "Show stats for the data type annotation"),
+       OPT_BOOLEAN(0, "insn-stat", &annotate.insn_stat,
+                   "Show instruction stats for the data type annotation"),
        OPT_END()
        };
        int ret;